#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp-ai.h> // AI库
#include <Adafruit_NeoPixel.h>  // ws2812 rgb灯带控制库
#include "serial.h"

// ================一些宏定义================//
// ws2812 rgb灯带
#define NUM_LEDS 12  // 灯珠数量
#define DATA_PIN 1   // 数据引脚


// ================一些宏定义================//

// ================ 一些函数定义 ================//
void rainbowRotate(); // 彩虹旋转
void idleEffect();
void listeningEffect(); // 添加语音识别状态效果函数声明
// 声明任务函数
void aiTask(void *parameter); // AI任务
void ledStripeTask(void *parameter); // 灯带任务
// void serialTask(void *parameter); // 串口任务
void onSessionStatus(String status); // 会话状态回调函数
void on_command(String command_id, String data); // 命令回调函数
// ================ 一些函数定义 ================//

// ================ 一些全局变量 ================//
// 创建NeoPixel对象
Adafruit_NeoPixel pixels(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
ESP_AI esp_ai;
String deviceStatus = "xxx";  // 设备状态
String LLMData = ""; // ai推理数据
int readLLMDataStatus = 1; // 读取LLM数据状态 1已读无需处理
// ================ 一些全局变量 ================//

void setup() {
  Serial.begin(115200);
  Serial1.begin(9600, SERIAL_8N1, UART_RX_PIN, UART_TX_PIN);
  pixels.begin();           // 初始化NeoPixel
  pixels.setBrightness(90); // 可选：设置亮度

  // 创建任务单独运行
  xTaskCreate(aiTask, "AITask", 1024 * 8, NULL, 3, NULL);           
  xTaskCreate(ledStripeTask, "ledStripeTask", 1024 * 2, NULL, 2, NULL); 
  xTaskCreate(serialTask, "SerialTask", 1024 * 3, NULL, 2, NULL);   
}

void aiTask(void *parameter)
{
  bool debug = true;
  ESP_AI_wifi_config wifi_config = {"Asnull-Net", "asnul666", "Asnull-AICar"};
  ESP_AI_server_config server_config = {"http", "aicar.lipux.cn", 8088, "p1=111&p2=test"}; // 服务器配置
  ESP_AI_wake_up_config wake_up_config = {"edge_impulse", 0.9, 10, "start", 5000, 500}; // 内置语音唤醒
  ESP_AI_volume_config volume_config = {.enable = false}; // 禁用音量控制
  ESP_AI_i2s_config_mic i2s_config_mic = {
      .bck_io_num = 4, // BCK引脚
      .ws_io_num = 5,  // WS引脚
      .data_in_num = 6 // DATA输入引脚
  };
  ESP_AI_i2s_config_speaker i2s_config_speaker = {15, 16, 7, 16000};
  // 重置按钮配置
  ESP_AI_reset_btn_config reset_btn_config = {10, "high"};
  ESP_AI_lights_config lights_config = {48};
  esp_ai.onSessionStatus(onSessionStatus);
  // 开始运行 ESP-AI
  esp_ai.begin({debug, wifi_config, server_config, wake_up_config, volume_config, i2s_config_mic, i2s_config_speaker, reset_btn_config, lights_config});
  esp_ai.setVolume(1);
  while (1)
  {
    // 开始运行AI
    esp_ai.loop();
    esp_ai.onEvent(on_command);
    // vTaskDelay(pdMS_TO_TICKS(10));
  }
}

void ledStripeTask(void *parameter){
  while (1)
  {
    if (deviceStatus == "xxx")
    {
      idleEffect();
    }
    else if (deviceStatus == "iat_start")
    { // 语音识别状态
      listeningEffect();
    }
    else
    {
      rainbowRotate();
    }
    vTaskDelay(pdMS_TO_TICKS(20));
  }
}



void loop() {
  vTaskDelay(pdMS_TO_TICKS(1000));
}


// 会话状态回调函数
void onSessionStatus(String status)
{
  // 处理会话状态
  deviceStatus = status;
  Serial.println("Session status: " + status);
}

// 监听服务器回调信息
void on_command(String command_id, String data) {
  if (command_id == "on_llm_cb") {
      Serial.println("Received command: " + command_id + " with data: " + data);
      LLMData = data; // 存储LLM数据
      readLLMDataStatus = 0; // 读取LLM数据状态 0未读需要处理
  }
} 


void rainbowRotate()
{
  static uint8_t hue = 0;
  static uint8_t offset = 0;

  for (int i = 0; i < NUM_LEDS; i++)
  {
    uint8_t led_hue = hue + (i * 255 / NUM_LEDS) + offset;
    uint32_t color = pixels.Color(
        (led_hue < 85) ? (255 - led_hue * 3) : (led_hue < 170) ? 0
                                                               : (led_hue - 170) * 3,
        (led_hue < 85) ? (led_hue * 3) : (led_hue < 170) ? (255 - (led_hue - 85) * 3)
                                                         : 0,
        (led_hue < 85) ? 0 : (led_hue < 170) ? ((led_hue - 85) * 3)
                                             : (255 - (led_hue - 170) * 3));

    pixels.setPixelColor(i, color);
  }

  pixels.show();
  hue += 1;
  offset += 5;
}

void idleEffect()
{
  static uint8_t brightness = 0;
  static bool increasing = true;

  // 呼吸灯效果
  for (int i = 0; i < NUM_LEDS; i++)
  {
    pixels.setPixelColor(i, pixels.Color(10, 10, brightness)); // 柔和的白色
  }
  pixels.show();

  // 亮度渐变
  if (increasing)
  {
    brightness += 1;
    if (brightness >= 30)
      increasing = false; // 限制最大亮度
  }
  else
  {
    brightness -= 1;
    if (brightness <= 5)
      increasing = true; // 限制最小亮度
  }

  vTaskDelay(pdMS_TO_TICKS(30)); // 控制呼吸速度
}

void listeningEffect()
{
  static uint8_t position = 0;
  static uint32_t lastChange = 0;

  // 蓝色跑马灯效果
  if (millis() - lastChange > 100)
  { // 每100ms移动一次
    pixels.clear();

    // 设置当前LED为蓝色
    pixels.setPixelColor(position, pixels.Color(0, 0, 100));

    // 设置前后两个LED为较暗蓝色
    if (position > 0)
    {
      pixels.setPixelColor(position - 1, pixels.Color(0, 0, 30));
    }
    if (position < NUM_LEDS - 1)
    {
      pixels.setPixelColor(position + 1, pixels.Color(0, 0, 30));
    }

    pixels.show();
    position = (position + 1) % NUM_LEDS;
    lastChange = millis();
  }
}